package chardet

var dict_gb = map[uint32]int{
	0xB5C4: 0x00, // 的
	0xD2BB: 0x01, // 一
	0xD4DA: 0x02, // 在
	0xC8CB: 0x03, // 人
	0xC1CB: 0x04, // 了
	0xD3D0: 0x05, // 有
	0xD6D0: 0x06, // 中
	0xCAC7: 0x07, // 是
	0xC4EA: 0x08, // 年
	0xBACD: 0x09, // 和
	0xB4F3: 0x0A, // 大
	0xB2BB: 0x0B, // 不
	0xB9A4: 0x0C, // 工
	0xC9CF: 0x0D, // 上
	0xB5D8: 0x0E, // 地
	0xCAD0: 0x0F, // 市
	0xD2AA: 0x10, // 要
	0xB3F6: 0x11, // 出
	0xD0D0: 0x12, // 行
	0xD7F7: 0x13, // 作
	0xC9FA: 0x14, // 生
	0xBCD2: 0x15, // 家
	0xD2D4: 0x16, // 以
	0xB3C9: 0x17, // 成
	0xB5BD: 0x18, // 到
	0xC8D5: 0x19, // 日
	0xC3F1: 0x1A, // 民
	0xCED2: 0x1B, // 我
	0xB2BF: 0x1C, // 部
	0xB6E0: 0x1D, // 多
	0xC8AB: 0x1E, // 全
	0xBDA8: 0x1F, // 建
	0xCBFB: 0x20, // 他
	0xB9AB: 0x21, // 公
	0xD5B9: 0x22, // 展
	0xC0ED: 0x23, // 理
	0xD0C2: 0x24, // 新
	0xB7BD: 0x25, // 方
	0xD6F7: 0x26, // 主
	0xC6F3: 0x27, // 企
	0xD6C6: 0x28, // 制
	0xD5FE: 0x29, // 政
	0xD3C3: 0x2A, // 用
	0xCDAC: 0x2B, // 同
	0xB7A8: 0x2C, // 法
	0xB8DF: 0x2D, // 高
	0xB1BE: 0x2E, // 本
	0xD4C2: 0x2F, // 月
	0xB6A8: 0x30, // 定
	0xBBAF: 0x31, // 化
	0xBCD3: 0x32, // 加
	0xBACF: 0x33, // 合
	0xC6B7: 0x34, // 品
	0xD6D8: 0x35, // 重
	0xB7D6: 0x36, // 分
	0xC1A6: 0x37, // 力
	0xCDE2: 0x38, // 外
	0xBECD: 0x39, // 就
	0xB5C8: 0x3A, // 等
	0xCFC2: 0x3B, // 下
	0xD4AA: 0x3C, // 元
	0xC9E7: 0x3D, // 社
	0xC7B0: 0x3E, // 前
	0xC3E6: 0x3F, // 面
	0xD2B2: 0x40, // 也
	0xD6AE: 0x41, // 之
	0xB6F8: 0x42, // 而
	0xC0FB: 0x43, // 利
	0xCEC4: 0x44, // 文
	0xCAC2: 0x45, // 事
	0xBFC9: 0x46, // 可
	0xB8C4: 0x47, // 改
	0xB8F7: 0x48, // 各
	0xBAC3: 0x49, // 好
	0xBDF0: 0x4A, // 金
	0xCBBE: 0x4B, // 司
	0xC6E4: 0x4C, // 其
	0xC6BD: 0x4D, // 平
	0xB4FA: 0x4E, // 代
	0xCCEC: 0x4F, // 天
}

// [\x00-\x7F]
// [\x81-\xFE][\x40-\x7E\x80-\xFE]
type gbk struct {
	byte
	rune
	hold [80]int
	ttls int
}

func (g gbk) String() string {
	return "gbk"
}

func (g *gbk) Feed(x byte) (ans bool) {
	if g.byte == 0 {
		if x >= 0x00 && x <= 0x7F {
			return true
		}
		if x >= 0x81 && x <= 0xFE {
			g.byte = 1
			g.rune = rune(x) << 8
			return true
		}
	} else {
		if (x >= 0x40 && x <= 0x7E) || (x >= 0x80 && x <= 0xFE) {
			g.byte = 0
			g.rune |= rune(x)
			g.count()
			return true
		}
	}
	return false
}

func (g *gbk) Priority() float64 {
	if g.ttls == 0 {
		return 0
	}
	f := 0.0
	for i, x := range g.hold {
		k := 100*float64(x)/float64(g.ttls) - freq_ch[i]
		if k >= 0 {
			f += k
		} else {
			f -= k
		}
	}
	return 100 - f
}

func (g *gbk) count() {
	if i, ok := dict_gb[uint32(g.rune)]; ok {
		g.hold[i]++
		g.ttls++
	}
}

// [\x00-\x7F]
// [\x81-\xFE][\x40-\x7E\x80-\xFE]
// [\x81-\xFE][\x30-\x39][\x81-\xFE][\x30-\x39]
type gb18030 struct {
	byte
}

func (g gb18030) String() string {
	return "gb18030"
}

func (g *gb18030) Feed(x byte) bool {
	switch g.byte {
	case 0:
		if x >= 0x00 && x <= 0x7F {
			return true
		}
		if x >= 0x81 && x <= 0xFE {
			g.byte = 1
			return true
		}
	case 1:
		if (x >= 0x40 && x <= 0x7E) || (x >= 0x80 && x <= 0xFE) {
			g.byte = 0
			return true
		}
		if x >= 0x30 && x <= 0x39 {
			g.byte = 2
			return true
		}
	case 2:
		if x >= 0x81 && x <= 0xFE {
			g.byte = 3
			return true
		}
	default:
		if x >= 0x30 && x <= 0x39 {
			g.byte = 0
			return true
		}
	}
	return false
}

func (g *gb18030) Priority() float64 {
	return -100
}
